package com.jintian.smart.kernel.orm.query;

import com.jintian.smart.kernel.orm.dto.Condition;
import com.jintian.smart.kernel.orm.query.impl.SqlQueryBuilder;
import lombok.Data;

@Data
public class Query {
    private static final int DEFAULT_PAGESIZE = 10;
    private static final int DEFAULT_TRACK_TOTAL_HITS = 10000;

    public enum AggType {
        TERMS;

    }

    private String[] tables;
    private Condition[] conditions;
    /**
     * %0 m %1 m (%2 s %3) 其中 0,1,2,3为conditions的序号 m = must = and , s = should = or
     */
    private String conditionFormat;
    private String[] columns;
    private String phrase;
    /**
     * 指定高亮字段
     */
    private String[] highLights;
    /**
     * 是否返回源数据
     */
    private boolean returnSource = true;
    /**
     * 基于数字1
     */
    private Integer pageNo;
    /**
     * 每页记录数
     */
    private Integer pageSize = DEFAULT_PAGESIZE;
    private Integer trackTotalHits = DEFAULT_TRACK_TOTAL_HITS;
    ;
    private boolean includeAllTerms = true;
    private String dateRange;
    private boolean summary = true;
    private Aggregate[] aggs;
    private String orderBy;

    public int offset() {
        return Math.max(pageNo != null && pageSize != null ? (pageNo - 1) * pageSize : 0, 0);
    }

    public Integer getPageSize() {
        return this.pageSize;
    }

    @Data
    public static class Aggregate {
        String name;
        AggType type;
        String field;
        int size = 100;
        Object[] values;

        // public AggregationBuilder esAggregationBuilder(Map<String, Object> options) {
        // switch (type) {
        // case TERMS:
        // return AggregationBuilders.terms(name).field(field).size(size);
        // default:
        // throw new IllegalArgumentException("暂未实现" + this + "的聚合");
        // }
        // }
    }

    public static class Mongodb {
        private static IQueryBuilder<?> INSTANCE = null;

        static {
            try {
                Class.forName("com.mongodb.client.model.Filters");
                INSTANCE = (IQueryBuilder<?>) Class.forName("com.jintian.smart.kernel.orm.query.impl.MongodbQueryBuilder")
                        .newInstance();
            } catch (Exception ex) {
            }
        }

        public static <T> T build(Query query, Class<T> clazz) throws Exception {
            return clazz.cast(INSTANCE.build(query));
        }

        public static Object build(Query query) throws Exception {
            return INSTANCE.build(query);
        }
    }

    public static class Sql {
        private static final IQueryBuilder<String> INSTANCE = new SqlQueryBuilder();

        public static String build(Query query) throws Exception {
            return INSTANCE.build(query);
        }
    }

    public static class ElastisSearch {
        private static IQueryBuilder<?> INSTANCE = null;

        static {
            try {
                Class.forName("org.elasticsearch.index.query.QueryBuilders");
                INSTANCE = (IQueryBuilder<?>) Class.forName("com.jintian.smart.kernel.orm.query.impl.ElastisSearchQueryBuilder")
                        .newInstance();
            } catch (Exception ex) {
            }
        }

        public static <T> T build(Query query, Class<T> clazz) throws Exception {
            return clazz.cast(INSTANCE.build(query));
        }

        public static Object build(Query query) throws Exception {
            return INSTANCE.build(query);
        }
    }

}
